home *** CD-ROM | disk | FTP | other *** search
/ Aminet 40 / Aminet 40 (2000)(Schatztruhe)[!][Dec 2000].iso / Aminet / dev / lang / Python16_Src.lha / Python16_Source / Modules / dlmodule.c < prev    next >
Encoding:
C/C++ Source or Header  |  2000-08-03  |  4.3 KB  |  221 lines

  1. /* dl module */
  2.  
  3. #include "Python.h"
  4.  
  5. #include <dlfcn.h>
  6.  
  7. #ifndef RTLD_LAZY
  8. #define RTLD_LAZY 1
  9. #endif
  10.  
  11. typedef ANY *PyUnivPtr;
  12. typedef struct {
  13.     PyObject_HEAD
  14.     PyUnivPtr *dl_handle;
  15. } dlobject;
  16.  
  17. staticforward PyTypeObject Dltype;
  18.  
  19. static PyObject *Dlerror;
  20.  
  21. static PyObject *
  22. newdlobject(handle)
  23.     PyUnivPtr *handle;
  24. {
  25.     dlobject *xp;
  26.     xp = PyObject_New(dlobject, &Dltype);
  27.     if (xp == NULL)
  28.         return NULL;
  29.     xp->dl_handle = handle;
  30.     return (PyObject *)xp;
  31. }
  32.  
  33. static void
  34. dl_dealloc(xp)
  35.     dlobject *xp;
  36. {
  37.     if (xp->dl_handle != NULL)
  38.         dlclose(xp->dl_handle);
  39.     PyObject_Del(xp);
  40. }
  41.  
  42. static PyObject *
  43. dl_close(xp, args)
  44.     dlobject *xp;
  45.     PyObject *args;
  46. {
  47.     if (!PyArg_Parse(args, ""))
  48.         return NULL;
  49.     if (xp->dl_handle != NULL) {
  50.         dlclose(xp->dl_handle);
  51.         xp->dl_handle = NULL;
  52.     }
  53.     Py_INCREF(Py_None);
  54.     return Py_None;
  55. }
  56.  
  57. static PyObject *
  58. dl_sym(xp, args)
  59.     dlobject *xp;
  60.     PyObject *args;
  61. {
  62.     char *name;
  63.     PyUnivPtr *func;
  64.     if (!PyArg_Parse(args, "s", &name))
  65.         return NULL;
  66.     func = dlsym(xp->dl_handle, name);
  67.     if (func == NULL) {
  68.         Py_INCREF(Py_None);
  69.         return Py_None;
  70.     }
  71.     return PyInt_FromLong((long)func);
  72. }
  73.  
  74. static PyObject *
  75. dl_call(xp, args)
  76.     dlobject *xp;
  77.     PyObject *args; /* (varargs) */
  78. {
  79.     PyObject *name;
  80.     long (*func)();
  81.     long alist[10];
  82.     long res;
  83.     int i;
  84.     int n = PyTuple_Size(args);
  85.     if (n < 1) {
  86.         PyErr_SetString(PyExc_TypeError, "at least a name is needed");
  87.         return NULL;
  88.     }
  89.     name = PyTuple_GetItem(args, 0);
  90.     if (!PyString_Check(name)) {
  91.         PyErr_SetString(PyExc_TypeError,
  92.                 "function name must be a string");
  93.         return NULL;
  94.     }
  95.     func = dlsym(xp->dl_handle, PyString_AsString(name));
  96.     if (func == NULL) {
  97.         PyErr_SetString(PyExc_ValueError, dlerror());
  98.         return NULL;
  99.     }
  100.     if (n-1 > 10) {
  101.         PyErr_SetString(PyExc_TypeError,
  102.                 "too many arguments (max 10)");
  103.         return NULL;
  104.     }
  105.     for (i = 1; i < n; i++) {
  106.         PyObject *v = PyTuple_GetItem(args, i);
  107.         if (PyInt_Check(v))
  108.             alist[i-1] = PyInt_AsLong(v);
  109.         else if (PyString_Check(v))
  110.             alist[i-1] = (long)PyString_AsString(v);
  111.         else if (v == Py_None)
  112.             alist[i-1] = (long) ((char *)NULL);
  113.         else {
  114.             PyErr_SetString(PyExc_TypeError,
  115.                    "arguments must be int, string or None");
  116.             return NULL;
  117.         }
  118.     }
  119.     for (; i <= 10; i++)
  120.         alist[i-1] = 0;
  121.     res = (*func)(alist[0], alist[1], alist[2], alist[3], alist[4],
  122.               alist[5], alist[6], alist[7], alist[8], alist[9]);
  123.     return PyInt_FromLong(res);
  124. }
  125.  
  126. static PyMethodDef dlobject_methods[] = {
  127.     {"call",    (PyCFunction)dl_call,    1 /* varargs */},
  128.     {"sym",     (PyCFunction)dl_sym},
  129.     {"close",    (PyCFunction)dl_close},
  130.     {NULL,      NULL}             /* Sentinel */
  131. };
  132.  
  133. static PyObject *
  134. dl_getattr(xp, name)
  135.     dlobject *xp;
  136.     char *name;
  137. {
  138.     return Py_FindMethod(dlobject_methods, (PyObject *)xp, name);
  139. }
  140.  
  141.  
  142. static PyTypeObject Dltype = {
  143.     PyObject_HEAD_INIT(&PyType_Type)
  144.     0,            /*ob_size*/
  145.     "dl",            /*tp_name*/
  146.     sizeof(dlobject),    /*tp_basicsize*/
  147.     0,            /*tp_itemsize*/
  148.     /* methods */
  149.     (destructor)dl_dealloc, /*tp_dealloc*/
  150.     0,            /*tp_print*/
  151.     (getattrfunc)dl_getattr,/*tp_getattr*/
  152.     0,            /*tp_setattr*/
  153.     0,            /*tp_compare*/
  154.     0,            /*tp_repr*/
  155.     0,            /*tp_as_number*/
  156.     0,            /*tp_as_sequence*/
  157.     0,            /*tp_as_mapping*/
  158.     0,            /*tp_hash*/
  159. };
  160.  
  161. static PyObject *
  162. dl_open(self, args)
  163.     PyObject *self;
  164.     PyObject *args;
  165. {
  166.     char *name;
  167.     int mode;
  168.     PyUnivPtr *handle;
  169.     if (PyArg_Parse(args, "z", &name))
  170.         mode = RTLD_LAZY;
  171.     else {
  172.         PyErr_Clear();
  173.         if (!PyArg_Parse(args, "(zi)", &name, &mode))
  174.             return NULL;
  175. #ifndef RTLD_NOW
  176.         if (mode != RTLD_LAZY) {
  177.             PyErr_SetString(PyExc_ValueError, "mode must be 1");
  178.             return NULL;
  179.         }
  180. #endif
  181.     }
  182.     handle = dlopen(name, mode);
  183.     if (handle == NULL) {
  184.         PyErr_SetString(Dlerror, dlerror());
  185.         return NULL;
  186.     }
  187.     return newdlobject(handle);
  188. }
  189.  
  190. static PyMethodDef dl_methods[] = {
  191.     {"open",    dl_open},
  192.     {NULL,        NULL}        /* sentinel */
  193. };
  194.  
  195. void
  196. initdl()
  197. {
  198.     PyObject *m, *d, *x;
  199.  
  200.     if (sizeof(int) != sizeof(long) ||
  201.         sizeof(long) != sizeof(char *)) {
  202.         PyErr_SetString(PyExc_SystemError,
  203.  "module dl requires sizeof(int) == sizeof(long) == sizeof(char*)");
  204.         return;
  205.     }
  206.  
  207.     /* Create the module and add the functions */
  208.     m = Py_InitModule("dl", dl_methods);
  209.  
  210.     /* Add some symbolic constants to the module */
  211.     d = PyModule_GetDict(m);
  212.     Dlerror = x = PyErr_NewException("dl.error", NULL, NULL);
  213.     PyDict_SetItemString(d, "error", x);
  214.     x = PyInt_FromLong((long)RTLD_LAZY);
  215.     PyDict_SetItemString(d, "RTLD_LAZY", x);
  216. #ifdef RTLD_NOW
  217.     x = PyInt_FromLong((long)RTLD_NOW);
  218.     PyDict_SetItemString(d, "RTLD_NOW", x);
  219. #endif
  220. }
  221.